using System.Collections.Generic;

namespace OracleInternal.BulkCopy
{
	internal class DirectPathRow
	{
		private static Queue<DirectPathRow> s_directPathRowCache;

		private static object s_directPathRowCacheLock;

		internal List<DirectPathRowPiece> m_rowPieces = new List<DirectPathRowPiece>();

		private bool m_bIsAllFastType;

		private int m_rowSize;

		private static int m_count;

		internal int Size => m_rowSize;

		static DirectPathRow()
		{
			s_directPathRowCache = new Queue<DirectPathRow>();
			s_directPathRowCacheLock = new object();
		}

		internal static void AddToCache(DirectPathRow dpRow)
		{
			dpRow.Reset();
			lock (s_directPathRowCacheLock)
			{
				s_directPathRowCache.Enqueue(dpRow);
			}
		}

		internal static void AddToCache(List<DirectPathRow> dpRows)
		{
			lock (s_directPathRowCacheLock)
			{
				for (int i = 0; i < dpRows.Count; i++)
				{
					dpRows[i].Reset();
					s_directPathRowCache.Enqueue(dpRows[i]);
				}
			}
		}

		internal static DirectPathRow GetFromCache(bool bFastType)
		{
			lock (s_directPathRowCacheLock)
			{
				if (s_directPathRowCache.Count > 0)
				{
					DirectPathRow directPathRow = s_directPathRowCache.Dequeue();
					directPathRow.m_bIsAllFastType = bFastType;
					return directPathRow;
				}
				return new DirectPathRow(bFastType);
			}
		}

		internal void Reset()
		{
			DirectPathRowPiece.AddToCache(m_rowPieces);
			m_rowPieces.Clear();
			m_bIsAllFastType = false;
			m_rowSize = 0;
		}

		internal void Initialize(bool bFastType)
		{
			m_bIsAllFastType = bFastType;
		}

		private DirectPathRow(bool bFastTypes)
		{
			m_bIsAllFastType = bFastTypes;
		}

		internal void AddPiece(DirectPathRowPiece rowPiece)
		{
			m_rowPieces.Add(rowPiece);
			m_rowSize += rowPiece.RowPieceLen;
		}

		private void RemovePiece(DirectPathRowPiece rowPiece)
		{
			if (m_rowPieces.Remove(rowPiece))
			{
				m_rowSize -= rowPiece.RowPieceLen;
			}
		}

		internal static DirectPathRow SplitRow(int requestedRowSize, DirectPathRow rowToSplit)
		{
			int num = 0;
			DirectPathRow directPathRow = null;
			if (requestedRowSize < rowToSplit.Size)
			{
				return null;
			}
			directPathRow = GetFromCache(rowToSplit.m_bIsAllFastType);
			int num2 = 0;
			for (int i = 0; i < rowToSplit.m_rowPieces.Count; i++)
			{
				DirectPathRowPiece directPathRowPiece = rowToSplit.m_rowPieces[i];
				num2 = directPathRowPiece.RowPieceLen;
				if (num + num2 > requestedRowSize)
				{
					directPathRow.AddPiece(directPathRowPiece);
					rowToSplit.RemovePiece(directPathRowPiece);
				}
				num += num2;
			}
			return directPathRow;
		}
	}
}
